//
//  TestPipeWC.m
//  sandbox
//
//  Created by 杨岑 on 6/6/15.
//  Copyright (c) 2015 杨岑. All rights reserved.
//

#import "TestPipeWC.h"

@interface TestPipeWC ()
@property (unsafe_unretained) IBOutlet NSTextView *output;
@property (weak) IBOutlet NSTextField *input;
@property (weak) IBOutlet NSTextField *arguments;

@end

@implementation TestPipeWC
{
    NSMutableArray* _objs;
}

- (void)awakeFromNib
{
    _objs = [NSMutableArray array];
    self.output.font = [NSFont userFixedPitchFontOfSize:13];
}

- (IBAction)run_click:(id)sender {
    self.output.string = @"";
    
    NSPipe* pipeError = [NSPipe pipe];
    NSPipe* pipeInput = [NSPipe pipe];
    NSPipe* pipeOutput = [NSPipe pipe];
    
    [_objs addObject:pipeError];
    [_objs addObject:pipeInput];
    [_objs addObject:pipeOutput];
    
    NSFileHandle* fhError = [pipeError fileHandleForReading];
    NSFileHandle* fhInput = [pipeInput fileHandleForWriting];
    NSFileHandle* fhOutput = [pipeOutput fileHandleForReading];
    
    NSNotificationCenter* nc = [NSNotificationCenter defaultCenter];
    [nc addObserver:self selector:@selector(handleErrorReading:) name:NSFileHandleDataAvailableNotification object:fhError];
    [nc addObserver:self selector:@selector(handleOutputReading:) name:NSFileHandleDataAvailableNotification object:fhOutput];
    
    [fhError waitForDataInBackgroundAndNotify];
    [fhOutput waitForDataInBackgroundAndNotify];

    NSArray* args;
    NSString* s = self.arguments.stringValue;
    if (s.length > 0)
    {
        args = [s componentsSeparatedByString:@"\n"];
        NSLog(@"Args: %@", args);
    }
    
    NSTask* task = [[NSTask alloc] init];
    [_objs addObject:task];
    
    task.standardError = pipeError;
    task.standardInput = pipeInput;
    task.standardOutput = pipeOutput;
    if (args.count) task.arguments = args;
    task.launchPath = self.input.stringValue;
    task.currentDirectoryPath = @"/tmp";
    
    NSOperationQueue* q = [[NSOperationQueue alloc] init];
    [q addOperationWithBlock:^{
        NSLog(@"Launching task: %@", task);
        @try
        {
            [task launch];
            
            //[NSThread sleepForTimeInterval:3];
            char* fakeInputData = "select 'string returned by SQL SELECT' as test;\n";
            NSData* data = [NSData dataWithBytes:fakeInputData length:strlen(fakeInputData)];
            [fhInput writeData:data];
            
            //[NSThread sleepForTimeInterval:3];
            //[fhInput closeFile];

            [task waitUntilExit];
            NSLog(@"Task ended with code: %d", task.terminationStatus);
            //[NSThread sleepForTimeInterval:3];
            //NSLog(@"Task operation ended");
        }
        @catch(NSException* ex)
        {
            NSLog(@"%@", ex);
        }
    }];
}

- (void)handleErrorReading:(NSNotification*)notification {
    NSFileHandle* fh = notification.object;
    //NSData* data = notification.userInfo[NSFileHandleNotificationDataItem];
    NSData* data = fh.availableData;
    if (data.length > 0)
    {
        NSString* s = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
        if (s.length > 0)
        {
            s = [NSString stringWithFormat:@"Error output: %@", s];
            NSDictionary* attrs = @{
                                    NSFontAttributeName: [NSFont userFixedPitchFontOfSize:13],
                                    NSForegroundColorAttributeName: [NSColor redColor]
                                    };
            NSAttributedString* as = [[NSAttributedString alloc] initWithString:s attributes:attrs];
            //NSAttributedString* lf = [[NSAttributedString alloc] initWithString:@"\n"];
            
            //[self.output.textStorage appendAttributedString:lf];
            [self.output.textStorage appendAttributedString:as];
            //[self.output.textStorage appendAttributedString:lf];
        }
        [fh waitForDataInBackgroundAndNotify];
    }
    else
    {
        NSNotificationCenter* nc = [NSNotificationCenter defaultCenter];
        [nc removeObserver:self name:NSFileHandleDataAvailableNotification object:fh];
        [_objs removeObject:fh];
    }
    
}

- (void)handleOutputReading:(NSNotification*)notification {
    NSFileHandle* fh = notification.object;
    //NSLog(@"%@", [NSThread currentThread]);
    
    //NSData* data = notification.userInfo[NSFileHandleNotificationDataItem];
    NSData* data = fh.availableData;
    if (data.length > 0)
    {
        NSString* s = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
        if (s)
        {
            NSDictionary* attrs = @{NSFontAttributeName: [NSFont userFixedPitchFontOfSize:13],
                                    NSForegroundColorAttributeName: [NSColor labelColor]
                                    };
            NSAttributedString* as = [[NSAttributedString alloc] initWithString:s attributes:attrs];
            //NSAttributedString* lf = [[NSAttributedString alloc] initWithString:@"\n"];
            
            //[self.output.textStorage appendAttributedString:lf];
            [self.output.textStorage appendAttributedString:as];
            //[self.output.textStorage appendAttributedString:lf];
            [self.output scrollRangeToVisible:NSMakeRange(self.output.string.length, 0)];
        }
        [fh waitForDataInBackgroundAndNotify];
    }
    else
    {
        NSNotificationCenter* nc = [NSNotificationCenter defaultCenter];
        [nc removeObserver:self name:NSFileHandleDataAvailableNotification object:fh];
        [_objs removeObject:fh];
    }
}


@end
